home *** CD-ROM | disk | FTP | other *** search
- /* > np
- * (C) Alan Williams 1990
- * Source file for a program to copy stdin to an Econet printer server
- * in 80 byte chunks.
- *
- * The idea is that you can use it as a pipe end. For example
- * $ cat file | netprint
- * will print the file on an Econet printer server.
- * One optional parameter is permited. That is the Econet address of the
- * server. Acceptable syntax include net.station station and a name.
- * For example 1.150, 235, and Laser2 will all work.
- * The name form is prefered as it will error faster if the server is not
- * free.
- *
- * This program prefers to have public read access to /dev/cmos.
- * root may have to set this otherwise 0.235 will be assumed.
- *
- *
- * Started 1pm 15/9/1990.
- * Worked first 4:30pm 16/9/1990
- * A little more on 17/9/1990 ( started on the /dev/cmos bit.)
- * A little more on 18/9/1990 ( it's not that easy.....)
- * did some work on the printer poll bit instead.
- * A little more on 1/10/1990 ( More work on /dev/cmos bit.)
- */
-
- #include <stdio.h>
- #include <strings.h>
- #include "sys/ioctl.h"
- #include "dev/econet.h"
-
- unsigned char buffer[80];
- int bufferptr;
- int h,i;
- int seq;
-
- struct netaddr {
- unsigned char station;
- unsigned char net;
- }
- ;
-
- struct netaddr server;
-
- void quithandler() {
- /* Intended to be called on close down. It should free ports and close
- down gracefully.
- */
- if (h!=0) close(h);
- }
-
- void error(char *s){
- printf("%s\n",s);
- quithandler();
- exit(1);
- }
-
- int claimeconetport(int port,int h){
- return(ioctl(h,ECOCLAIMPORT,&port));
- }
-
- void getserverbyname(char *s)
- {
- int rc;
- struct eco_op tx,rp;
- if (strlen(s) >6 ) error("netprint: server name too long.");
- strcpy(buffer," ");
- strcpy(buffer,s);
- buffer[strlen(s)]=' ';
- buffer[6]=0x01;
- buffer[7]=0x00;
-
- tx.eco_tx_data_ptr = (int) buffer;
- tx.eco_tx_data_length = 8;
- tx.eco_station = 0xFF;
- tx.eco_net = 0xFF;
- tx.eco_control = 0;
- tx.eco_port = 0x9F;
- rc=ioctl(h,ECOTRANSMIT,&tx);
-
- if (rc==-1) error("netprint: net error.");
- rp.eco_buffers = 1;
- rp.eco_rx_group = 0;
- rp.eco_station = 0;
- rp.eco_net = 0;
- rp.eco_control = 0;
- rp.eco_port = 0x9E;
- rc=ioctl(h,ECOENABLERECEPTION,&rp);
- rp.eco_time_wait= 200;
- rc=ioctl(h,ECOAWAITRECEPTIONTIMED,&rp);
- rc=ioctl(h,ECOBUFFERSTATUS,&rp);
- if (rp.eco_data_length == 0 ) error("Can't find named printer.");
- rp.eco_data_ptr = (int) buffer;
- rc=ioctl(h,ECOBUFFERREAD,&rp);
- if (buffer[0] == 1) error("Printer is bussy.");
- if (buffer[0] == 2) error("netprint: printer is jammed.");
- /* rc=ioctl(h,ECOBUFFERKILL,&rp); */
-
- server.net = rp.eco_net;
- server.station = rp.eco_station;
- }
-
-
- void defaultservernumber()
- /* Now reads from /dev/cmos to find out defaults */
- {
- int n,f;
-
- /* server.net=0;
- * server.station=235;
- * old code now redundant
- */
-
- f=open("/dev/cmos",0,0);
- /* RISC OS PRM Pages 783..786 for CMOS ram mappings
- * This code tries to read the first five bytes of CMOS ram
- */
-
- n=read(f,buffer+10,5);
- if (n==-1) {
- printf("netprint: can't read /dev/cmos. Using 0.235\n");
- server.net=0;
- server.station=235;
- return;
- }
- printf("File handle for /dev/cmos is %d\n",n);
- printf("CMOS ram read results \n");
- printf(" 0 1 2 3 4 5 \n");
- printf("%d %d %d %d %d %d \n",buffer[10],buffer[11],buffer[12],buffer[13],buffer[14]);
- printf("%d \n",buffer[13]);
- if (buffer[13]==0) {
- lseek(f,153L,0);
- n=read(f,buffer+15,5);
- buffer[20]=0;
- printf("Configured server name is %s\n", buffer+14);
- getserverbyname((char *) buffer+14);
- }
- else
- {
- server.net = buffer[14];
- server.station = buffer[13];
- }
- }
-
- void getservernumber(char *c) {
- int n1;
- char *dot;
- dot = index(c,'.');
- n1 = atoi(c);
- if ((dot==NULL) && (n1==0)) {
- /* Find printer via name broadcast */
- getserverbyname(c);
- }
- else {
- if (dot!=NULL) {
- server.station=atoi(dot+1);
- server.net=n1;
- }
- else {
- server.net=0;
- server.station=n1;
- }
- if ((server.station > 254) | (server.station < 1 )) error("netprint: Bad econet station number.");
- }
- }
-
- void sendbuffer(int flags) {
- int rc;
- struct eco_op tx,rp;
- tx.eco_tx_data_ptr = (int) buffer;
- tx.eco_tx_data_length = bufferptr;
- tx.eco_station = server.station;
- tx.eco_net = server.net;
- tx.eco_control = seq | flags;
- tx.eco_port = 0xD1;
- rc=ioctl(h,ECOTRANSMIT,&tx);
-
- if (rc==-1) error("Net error.");
- seq = (seq + 1) % 2;
- rp.eco_buffers = 1;
- rp.eco_rx_group = 0;
- rp.eco_station = server.station;
- rp.eco_net = server.net;
- rp.eco_control = 0;
- rp.eco_port = 0xD1;
- rc=ioctl(h,ECOENABLERECEPTION,&rp);
- rp.eco_time_wait= 2000;
- rc=ioctl(h,ECOAWAITRECEPTIONTIMED,&rp);
- rc=ioctl(h,ECOBUFFERSTATUS,&rp);
- rc=ioctl(h,ECOBUFFERKILL,&rp);
- }
-
- void putinbuffer(char c) { /* intersting cast between int and char here! */
- buffer[bufferptr]=c;
- bufferptr+=1;
- if (bufferptr == 80) {
- sendbuffer(0);
- bufferptr = 0;
- }
- }
-
- int testserver(){
- /* open an RXCB for ps on port &9E
- do a TX on port &9F to ps with data = "PRINT" 01 00
- wait a reasonable time for a reply (1 second?)
- If no reply comes then we can't talk to this server.
- An interesting feature of the protocol is the fact that a server
- must respond to request on its own name (such as Laser etc) and
- to the name "PRINT " as well!!
- */
-
- int rc;
- struct eco_op tx,rp;
- strcpy(buffer,"PRINT ");
- buffer[6]=0x01;
- buffer[7]=0x00;
-
- tx.eco_tx_data_ptr = (int) buffer;
- tx.eco_tx_data_length = 8;
- tx.eco_station = server.station;
- tx.eco_net = server.net;
- tx.eco_control = 0;
- tx.eco_port = 0x9F;
- rc=ioctl(h,ECOTRANSMIT,&tx);
-
- if (rc==-1) error("netprint: printer not listening.");
- rp.eco_buffers = 1;
- rp.eco_rx_group = 0;
- rp.eco_station = server.station;
- rp.eco_net = server.net;
- rp.eco_control = 0;
- rp.eco_port = 0x9E;
- rc=ioctl(h,ECOENABLERECEPTION,&rp);
- rp.eco_time_wait= 200;
- rc=ioctl(h,ECOAWAITRECEPTIONTIMED,&rp);
- rc=ioctl(h,ECOBUFFERSTATUS,&rp);
- if (rp.eco_data_length == 0 ) error("netprint: no reply from printer");
- rp.eco_data_ptr = (int) buffer;
- rc=ioctl(h,ECOBUFFERREAD,&rp);
- if (buffer[0] == 1) error("Printer is bussy.");
- if (buffer[0] == 2) error("Printer is jammed.");
- return(1);
- }
-
- int logon(){
- /* open an RXCB for ps on port D1 for the reply
- * Then send the log on request and wait for the reply.
- */
- int rc,junk;
- struct eco_op log,rply;
- junk=0;
-
- rply.eco_buffers = 1;
- rply.eco_rx_group = 0;
- rply.eco_station = server.station;
- rply.eco_net = server.net;
- rply.eco_control = 0;
- rply.eco_port = 0xD1;
-
- log.eco_tx_data_ptr = (int) &junk;
- log.eco_tx_data_length = 1;
- log.eco_station = server.station;
- log.eco_net = server.net;
- log.eco_control = 0x02; /* 0x82 */
- log.eco_port = 0xD1;
- rc=ioctl(h,ECOTRANSMIT,&log);
- if (rc==-1) return(1);
- rc=ioctl(h,ECOENABLERECEPTION,&rply);
- rply.eco_time_wait = 2000;
- rc=ioctl(h,ECOAWAITRECEPTIONTIMED,&rply);
- rc=ioctl(h,ECOBUFFERSTATUS,&rply);
- rc=ioctl(h,ECOBUFFERKILL,&rply);
- if (rply.eco_data_length=0) return 1 ; /* no reply in time */
- /* assume that we are logged on to the printer server now */
- return 0;
- }
-
- void logoff() {
- bufferptr+=1;
- sendbuffer(4);
- }
-
- int main(int argc,char *argv[]) {
- int b;
- h=0;
- seq=1;
-
- if ((h=open("/dev/ecof",0,0))==-1)error("Can't open econet dev.");
- if (claimeconetport(0xD1,h)!=0) error("Can't claim port &D1.");
- if (claimeconetport(0x9E,h)!=0) error("Can't claim port &9E.");
- if (claimeconetport(0x9F,h)!=0) error("Can't claim port &9F.");
- if (argc==2)
- getservernumber(argv[1]);
- else
- defaultservernumber();
- printf("Server is found at %d.%d\n",server.net,server.station);
- /* error("Debugging\n"); */
- if (testserver()) {
- if (logon()!=0) error("Can't log on to server.");
- while ((b=getchar())!= EOF)
- putinbuffer(b);
- logoff();
- }
- quithandler();
- return 0;
- } /* main */
-